{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Import Libraries*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import scipy.io\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "import sys \n",
    "sys.path.append('/home/bhustali/.conda/envs/tf2/svcca-master')\n",
    "import cca_core"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Simple Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 227,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "adding eps to diagonal and taking inverse\n",
      "taking square root\n",
      "dot products...\n",
      "trying to take final svd\n",
      "computed everything!\n",
      "Returned Information:  \n",
      "\n",
      "dict_keys(['coef_x', 'invsqrt_xx', 'full_coef_x', 'full_invsqrt_xx', 'coef_y', 'invsqrt_yy', 'full_coef_y', 'full_invsqrt_yy', 'neuron_means1', 'neuron_means2', 'cca_coef1', 'cca_coef2', 'x_idxs', 'y_idxs', 'mean', 'sum', 'cca_dirns1', 'cca_dirns2'])\n",
      "Single number for summarizing similarity\n",
      "0.0841\n"
     ]
    }
   ],
   "source": [
    "# # assume A_fake has 20 neurons and we have their activations on 2000 datapoints\n",
    "# A_fake = np.random.randn(20, 2000)\n",
    "\n",
    "# # B_fake has 50 neurons with activations on the same 1000 datapoints\n",
    "# # Note A and B do *not* have to have the same number of neurons\n",
    "# B_fake = np.random.randn(50, 1000)\n",
    "\n",
    "# # computing CCA simliarty between A_fake, B_fake\n",
    "# # We expect similarity should be very low, because the random activations are not correlated\n",
    "# results = cca_core.get_cca_similarity(A_fake, B_fake,compute_dirns=True, verbose=True)\n",
    "\n",
    "# print(\"Returned Information:  \\n\")\n",
    "# print(results.keys())\n",
    "# print(\"Single number for summarizing similarity\")\n",
    "# print('{:.4f}'.format(np.mean(results[\"cca_coef1\"])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SVCCA Layers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for k in range(1,587):\n",
    "    \n",
    "    data_A = scipy.io.loadmat('/home/bhustali/data/mat/neuron_output (586).mat')\n",
    "    data_B = scipy.io.loadmat('/home/bhustali/data/mat/neuron_output ' + '('  + str(k)+ ')' + '.mat')\n",
    "    \n",
    "    S = np.zeros((8,8))\n",
    "    \n",
    "    for i in range (1,9):\n",
    "        for j in range (1,9):\n",
    "            \n",
    "            #extract layer outputs l_1 and l_2\n",
    "            A_layer = data_A['layer_' + str(i)].transpose()\n",
    "            B_layer = data_B['layer_' + str(j) ].transpose()\n",
    "            \n",
    "            # Mean subtract activations\n",
    "            '''\n",
    "            a = np.array([[1, 2], [3, 4]])\n",
    "            np.mean(a, axis=1) = array([1.5, 3.5]) \n",
    "            '''\n",
    "            c_A_layer = A_layer - np.mean(A_layer, axis=1, keepdims=True)\n",
    "            c_B_layer = B_layer - np.mean(B_layer, axis=1, keepdims=True)\n",
    "            \n",
    "            #Singular Value Decomposition(SVD)\n",
    "            #obtain l_1' and l_2'\n",
    "            '''\n",
    "            U, S, Vh = np.linalg.svd(A, full_matrices=False)\n",
    "\n",
    "            U  = [mxs] = Left-singular vector of A\n",
    "            S  = [sxs] = Singular values of A\n",
    "            Vh = [sxp] = Right-singular vectors of A\n",
    "            '''\n",
    "            u_A, s_A, vh_A = np.linalg.svd(c_A_layer, full_matrices=False)\n",
    "            u_B, s_B, vh_B = np.linalg.svd(c_B_layer, full_matrices=False)\n",
    "            \n",
    "            sv = 10 #select an appropriate value\n",
    "\n",
    "#             print(\"Percentage of variance explained by 'sv' singular vectors\", 100*np.sum(s_A[:sv])/np.sum(s_A))\n",
    "\n",
    "            '''singular vectors = S * Vh \n",
    "            Equivalent to Uh * A = Uh* (U*S*Vh) = S*Vh\n",
    "            '''\n",
    "            #We compute the subspace with 'sv' largest singular values\n",
    "            sv_A_layer = np.matmul(s_A[:sv]*np.eye(sv), vh_A[:sv])\n",
    "            sv_B_layer = np.matmul(s_B[:sv]*np.eye(sv), vh_B[:sv])\n",
    "           \n",
    "            svcca_results = cca_core.get_cca_similarity(sv_A_layer, sv_B_layer, epsilon=0, threshold=1,compute_dirns=True, verbose=False)\n",
    "        \n",
    "            S[i-1,j-1] = np.mean(svcca_results[\"cca_coef1\"])\n",
    "            \n",
    "            fig, ax = plt.subplots()\n",
    "            ax.matshow(S, cmap=plt.cm.Blues)\n",
    "            ax.set_xticklabels([0,'B1','B2','B3','B4','B5','B6','B7','B8'])\n",
    "            ax.set_yticklabels([0,'A1','A2','A3','A4','A5','A6','A7','A8'])\n",
    "\n",
    "            for l in range(8):\n",
    "                for m in range(8):\n",
    "                    c = S[m,l]\n",
    "                    ax.text(l, m, f\"{c:.2f}\", va='center', ha='center')\n",
    "\n",
    "            plt.savefig('/home/bhustali/data/movie/' + str(k) + '.png',dpi = 100)\n",
    "            \n",
    "            plt.close('all')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
